package com.gm.corejava.book2;

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created with IntelliJ IDEA.
 * User: camark@sina.cn
 * Date: 13-12-30
 * Time: 上午10:46
 */
public class MessageDigestFrame extends JFrame {

    private JTextArea message=new JTextArea();
    private JTextField digest=new JTextField();
    private MessageDigest currentDigest;

    public MessageDigestFrame(){
        setTitle("Message Digest Frame");
        setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);

        JPanel panel=new JPanel();
        ButtonGroup group=new ButtonGroup();
        addRadioButton(panel,"SHA-1",group);
        addRadioButton(panel,"MD5",group);
        add(panel, BorderLayout.NORTH);

        add(new JScrollPane(message),BorderLayout.CENTER);
        add(digest,BorderLayout.SOUTH);

        setAlgorithm("SHA-1");

        JMenuBar menuBar=new JMenuBar();
        JMenu fileMenu=new JMenu("File");
        JMenuItem fileDigestItem=new JMenuItem("File Digest");
        fileMenu.add(fileDigestItem);
        fileDigestItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                loadFile();
            }
        });

        JMenuItem textDigestItem=new JMenuItem("Text Digest");
        fileMenu.add(textDigestItem);
        textDigestItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String m = message.getText();
                compDigest(m.getBytes());
            }
        });

        menuBar.add(fileMenu);
        setJMenuBar(menuBar);
    }

    private void addRadioButton(JPanel panel, final String s, ButtonGroup group) {
        ActionListener listener=new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setAlgorithm(s);
            }
        };

        JRadioButton b=new JRadioButton(s,group.getButtonCount()==0);
        panel.add(b);
        group.add(b);
        b.addActionListener(listener);
    }

    private void setAlgorithm(String s){
        try{
        currentDigest=MessageDigest.getInstance(s);
        digest.setText("");
        }catch (NoSuchAlgorithmException e){
            digest.setText(" "+e);
        }
    }
    private void compDigest(byte[] bytes) {
        currentDigest.reset();
        currentDigest.update(bytes);

        byte[] hash=currentDigest.digest();

        StringBuilder s=new StringBuilder();

        for(int i=0;i<hash.length;i++){
            int v=hash[i] & 0xFF;
            if(v<16) s.append("0");

            s.append(Integer.toString(v,16).toUpperCase()+" ");
        }

        digest.setText(s.toString());
    }

    private void loadFile() {
        JFileChooser chooser=new JFileChooser();
        chooser.setCurrentDirectory(new File("."));

        int r=chooser.showOpenDialog(this);
        if(r==JFileChooser.APPROVE_OPTION){
            try{
                String fileName=chooser.getSelectedFile().getAbsolutePath();
                compDigest(loadBytes(fileName));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    private byte[] loadBytes(String fileName) throws IOException{
        FileInputStream fileInputStream=new FileInputStream(fileName);

        try{
            ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
            int ch;

            while((ch=fileInputStream.read())!=-1){
                byteArrayOutputStream.write(ch);
            }

            return byteArrayOutputStream.toByteArray();
        }finally{
            fileInputStream.close();
        }
    }

    private final int DEFAULT_WIDTH=400;
    private final int DEFAULT_HEIGHT=400;
}